package com.ibl.rover.lite.client.Application;

import java.io.File;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import com.ibl.rover.lite.client.Logger;
import com.ibl.rover.lite.client.R;
import com.ibl.rover.lite.client.RoverLiteClientActivity;
import com.ibl.rover.lite.client.Application.Properties.ApplicationProperties;
import com.ibl.rover.lite.client.DatabaseSource.DataSourceFactory;
import com.ibl.rover.lite.client.Helper.DatabaseBeanHelper;
import com.ibl.rover.lite.client.Sync.Parser.ResponseHandler;
import com.ibl.rover.lite.client.Sync.Parser.SyncRequestBuilder;
import com.ibl.rover.lite.common.bean.AppSetupBean;
import com.ibl.rover.lite.common.bean.CustomerBean;
import com.ibl.rover.lite.common.bean.DefaultRouteBean;
import com.ibl.rover.lite.common.bean.OrderBean;
import com.ibl.rover.lite.common.bean.ProductBean;
import com.ibl.rover.lite.common.bean.ProductCategroy;
import com.ibl.rover.lite.common.bean.ProductOrderBean;
import com.ibl.rover.lite.common.bean.RouteBean;
import com.ibl.rover.lite.common.bean.SettingBean;
import com.ibl.rover.lite.common.bean.UserBean;
import com.ibl.rover.lite.common.db.BaseException;
import com.ibl.rover.lite.common.db.Criteria;
import com.ibl.rover.lite.common.db.Criteria.Operators;
import com.ibl.rover.lite.common.db.DatabaseManager;
import com.mobile.sync.client.Sync.HttpConfiguration;
import com.mobile.sync.client.Sync.impl.HTTPSyncImpl;
import com.mobile.sync.client.Sync.impl.HTTPSyncImplFactory;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class ApplicationContext extends Application {

	private static ApplicationProperties appParam = null;
	private Resources resources = null;
	private Logger logger = null;
	private String deviceId;
	private String[] skuName;
	private String versionCode;
	private DatabaseManager databaseManager = null;
	private HashMap<Integer, Object> viewContext = new HashMap<Integer, Object>();
	private String userName;
	private SyncRequestBuilder syncRequestBuilder;
	private HTTPSyncImpl httpSyncImpl = null;
	public static UserBean loggedUser = null;
	public static final String CUR_USER_EXT = ".user";
	private HttpConfiguration httpConfiguration;

	@Override
	public void onCreate() {
		super.onCreate();
		try {

			resources = getResources();

			Logger.init(this);
			logger = Logger.getLogger();
			logger.log("[Logger initialized in ApplicationContext::onCreate]");
			appParam = getAppParams();
			httpConfiguration = appParam.getHttpConfiguration();
			// httpSyncImpl = HTTPSyncImplFactory
			// .getTransportAgent(httpConfiguration);
			// httpSyncImpl.register(new ResponseHandler("[RESP_PARSE]"));

			TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
			deviceId = telephonyManager.getDeviceId();

			File file = getFilesDir();
			File[] listFiles = file.listFiles();
			for (File singleFile : listFiles) {
				if (singleFile.getAbsolutePath().endsWith(
						ApplicationContext.CUR_USER_EXT)) {
					String fileNameWithExt = singleFile.getName();
					String fileName = fileNameWithExt.substring(0,
							fileNameWithExt.lastIndexOf("."));
					logger.log("[Logged in user : " + fileName + "]");
					initialize(fileName);
				}
			}

			PackageInfo pInfo = null;
			try {
				pInfo = getPackageManager().getPackageInfo(
						"com.ibl.rover.lite", PackageManager.GET_META_DATA);
			} catch (NameNotFoundException e) {
				pInfo = null;
			}

			if (pInfo != null) {
				versionCode = Integer.toString(pInfo.versionCode);
			}

		} catch (Exception ex) {
			logger.logException("[Exception occured : ", ex);
		}
		logger.log("[ApplicationContext::onCreate .. Ends]");

	}

	/**
	 * Save Server Setting
	 */
	private void saveSettings() {
		try {

			Criteria<SettingBean> criteria = databaseManager
					.generateCriteria(SettingBean.class);
			SharedPreferences app_preferences = getSharedPreferences("SETTING",
					MODE_WORLD_WRITEABLE);
			getAppParams().getHttpConfiguration().setServerUrl(
					app_preferences.getString("IP", getAppParams()
							.getHttpConfiguration().getServerUrl()));
			getAppParams().getHttpConfiguration().setServerPort(
					Integer.parseInt(app_preferences.getString("PORT", String
							.valueOf(getAppParams().getHttpConfiguration()
									.getServerPort()))));

			if (criteria.execute().size() < 1) {
				SettingBean settingBean = new SettingBean();
				settingBean.setServerPort(String.valueOf(httpConfiguration
						.getServerPort()));
				settingBean.setServerUrl(httpConfiguration.getServerUrl());

				databaseManager.saveBean(settingBean);

			}

		} catch (Exception e) {
			logger.logException("saveSetting ", e);
		}
	}

	public void initialize(final String userName) {
		this.userName = userName;
		DatabaseOpenHelper helper = new DatabaseOpenHelper();
		databaseManager = DataSourceFactory.getResolverDataSource(helper);
		syncRequestBuilder = new SyncRequestBuilder(this);
		try {
			Criteria<UserBean> userSearch = databaseManager
					.generateCriteria(UserBean.class);

			userSearch.addRestriction(UserBean.COL_USER_NAME,
					Operators.isEqual, userName);

			List<UserBean> user = userSearch.execute();

			if (null != user && 0 < user.size()) {
				loggedUser = user.get(0);
			}
			saveSettings();
		} catch (BaseException ex) {
			ex.printStackTrace();
		}

	}

	public String[] getSkuTypes() {
		try {
			if (skuName == null) {
				Criteria<ProductCategroy> criteria = databaseManager
						.generateCriteria(ProductCategroy.class);
				List<ProductCategroy> list = criteria.execute();
				skuName = new String[list.size() + 1];
				int i = 1;
				skuName[0] = "All";
				for (ProductCategroy productCategroy : list) {
					skuName[i++] = productCategroy.getCategoryCode();
				}

			}

		} catch (Exception e) {
			logger.logException("GetException ", e);
		}
		return skuName;
	}

	public HTTPSyncImpl getHttpSyncImpl() {
		return httpSyncImpl;
	}

	public void setHttpSyncImpl(HTTPSyncImpl httpSyncImpl) {
		this.httpSyncImpl = httpSyncImpl;
	}

	public ProductCategroy getSkuByCategory(String categoryName) {
		try {
			if (!categoryName.equals("All")) {
				Criteria<ProductCategroy> criteria = databaseManager
						.generateCriteria(ProductCategroy.class);
				criteria.addRestriction(ProductCategroy.COL_CATEGORY_CODE,
						Operators.isEqual, categoryName);
				List<ProductCategroy> list = criteria.execute();
				if (list.size() > 0)
					return list.get(0);
			} else {
				return null;
			}
		} catch (Exception e) {
			logger.logException("GetException ", e);
		}
		return null;
	}

	public SyncRequestBuilder getSyncRequestBuilder() {
		return syncRequestBuilder;
	}

	public void setSyncRequestBuilder(SyncRequestBuilder syncRequestBuilder) {
		this.syncRequestBuilder = syncRequestBuilder;
	}

	public ApplicationProperties getAppParams() {
		if (null == appParam) {
			InputStream in = getResources()
					.openRawResource(R.raw.configuration);
			appParam = ApplicationProperties.getInstance(in);
		}
		return appParam;
	}

	public HashMap<Integer, Object> getViewContext() {
		return viewContext;
	}

	private class DatabaseOpenHelper implements DatabaseBeanHelper {

		@Override
		public Context getContext() {
			return ApplicationContext.this.getApplicationContext();
		}

		@Override
		public String getDatabaseName() {
			// TODO Auto-generated method stub
			return userName;
		}

		@Override
		public int getDatabaseVersion() {
			// TODO Auto-generated method stub
			return 1;
		}

		@Override
		public SQLLiteImplemenation getDatabaseImpl() {
			return SQLLiteImplemenation.SQLiteDatabase;
		}

		@Override
		public void onDatabaseCreate(DatabaseManager databaseManager) {
			UserBean userBean = new UserBean();
			RouteBean routeBean = new RouteBean();
			CustomerBean customerBean = new CustomerBean();
			ProductCategroy productCategroy = new ProductCategroy();
			ProductBean productBean = new ProductBean();
			OrderBean orderBean = new OrderBean();
			ProductOrderBean productOrderBean = new ProductOrderBean();
			AppSetupBean appSetupBean = new AppSetupBean();
			SettingBean settingBean = new SettingBean();
			DefaultRouteBean defaultRouteBean=new DefaultRouteBean();

			try {
				databaseManager.executeScaler(defaultRouteBean.getCreateTableQuery());
				databaseManager.executeScaler(userBean.getCreateTableQuery());
				databaseManager.executeScaler(routeBean.getCreateTableQuery());
				databaseManager.executeScaler(customerBean
						.getCreateTableQuery());
				databaseManager.executeScaler(productCategroy
						.getCreateTableQuery());
				databaseManager
						.executeScaler(productBean.getCreateTableQuery());
				databaseManager.executeScaler(orderBean.getCreateTableQuery());
				databaseManager.executeScaler(productOrderBean
						.getCreateTableQuery());
				databaseManager.executeScaler(appSetupBean
						.getCreateTableQuery());
				databaseManager
						.executeScaler(settingBean.getCreateTableQuery());

//				 dummy(databaseManager);
			} catch (Exception e) {
				e.printStackTrace();
				logger.logException("On Database Create Exception ", e);
			}

		}

	}

	/**
	 * Dummy Data
	 */
	private void dummy(DatabaseManager databaseManager) {
		try {
			AppSetupBean appSetupBean = new AppSetupBean();
			appSetupBean.setCode("MS207");
			appSetupBean.setLastOrder("20");
			appSetupBean.setName("Junaid");
			databaseManager.saveBean(appSetupBean);

			UserBean userBean = new UserBean();
			userBean.setUserName("JUNAID");
			userBean.setPassword("Junaid");
			userBean.setContact("adsasdasdas ");
			userBean.setRole("asdasd");
			userBean.setCellNumber("asdasd");
			userBean.setStreetAddress("asdasdasd");
			databaseManager.saveBean(userBean);

			CustomerBean customerBean = new CustomerBean();

			customerBean.setAddress("Custoemr 1 Address");
			customerBean.setCode("Customer 1Code");
			customerBean.setCreditLimit(0.3);
			customerBean.setName("Customer 1");
			customerBean.setRouteNumber(1);
			databaseManager.saveBean(customerBean);

			CustomerBean customerBean2 = new CustomerBean();
			customerBean2.setAddress("Custoemr 2 Address");
			customerBean2.setCode("Customer 2 Code");
			customerBean2.setCreditLimit(0.3);
			customerBean2.setName("Customer 2");
			customerBean2.setRouteNumber(2);
			databaseManager.saveBean(customerBean2);

			RouteBean routeBean = new RouteBean();
			routeBean.setCode("1");
			routeBean.setDay("2011-10-22");
			databaseManager.saveBean(routeBean);

			RouteBean routeBean2 = new RouteBean();
			routeBean2.setCode("2");
			routeBean2.setDay("2011-10-23");
			databaseManager.saveBean(routeBean2);

			RouteBean routeBean3 = new RouteBean();
			routeBean3.setCode("2");
			routeBean3.setDay("2011-10-24");
			databaseManager.saveBean(routeBean3);

			ProductCategroy productCategroy = new ProductCategroy();
			productCategroy.setCategoryCode("ESR");
			databaseManager.saveBean(productCategroy);
			productCategroy = null;
			productCategroy = new ProductCategroy();
			productCategroy.setCategoryCode("TBL");
			databaseManager.saveBean(productCategroy);
			productCategroy = null;
			productCategroy = new ProductCategroy();
			productCategroy.setCategoryCode("ICN");
			databaseManager.saveBean(productCategroy);

			ProductBean productBean = new ProductBean();
			productBean.setBrandCode("A100");
			productBean.setDescription("ES ESR 9W/865-B22");
			productBean.setDisplaySequence(1L);
			productBean.setProductCategoryId("ESR");
			productBean.setProductCode("G74579");
			productBean.setUnitPrice("100");
			databaseManager.saveBean(productBean);

			productBean = null;
			productBean = new ProductBean();
			productBean.setBrandCode("A100");
			productBean.setDescription("ES ESR 9W/865-E27");
			productBean.setDisplaySequence(2L);
			productBean.setProductCategoryId("ESR");
			productBean.setProductCode("G74581");
			productBean.setUnitPrice("100");
			databaseManager.saveBean(productBean);

			productBean = null;
			productBean = new ProductBean();
			productBean.setBrandCode("A100");
			productBean.setDescription("ES ICN 9W/865-F27");
			productBean.setDisplaySequence(2L);
			productBean.setProductCategoryId("ICN");
			productBean.setProductCode("G74582");
			productBean.setUnitPrice("100");
			databaseManager.saveBean(productBean);

			productBean = null;
			productBean = new ProductBean();
			productBean.setBrandCode("A100");
			productBean.setDescription("ES TBL 9W/865-F27");
			productBean.setDisplaySequence(2L);
			productBean.setProductCategoryId("TBL");
			productBean.setProductCode("G74584");
			productBean.setUnitPrice("100");
			databaseManager.saveBean(productBean);

		} catch (Exception e) {
			logger.logException("Dummy Exception:", e);
		}
	}

	public Logger getLogger() {
		return logger;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	public String getDeviceId() {
		return deviceId;
	}

	public void setDeviceId(String deviceId) {
		this.deviceId = deviceId;
	}

	public String getVersionCode() {
		return versionCode;
	}

	public void setVersionCode(String versionCode) {
		this.versionCode = versionCode;
	}

	public DatabaseManager getDatabaseManager() {
		return databaseManager;
	}

	/**
	 * Show Toast
	 * 
	 * @param message
	 *            of the Toast
	 */
	public void showMessage(String message, int toastLength) {
		Toast toast = Toast.makeText(this, message, toastLength);
		toast.show();
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

}
